package util

import (
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v5"
	"github.com/spf13/viper"
	"time"
)

var secret = []byte(viper.GetString("jwt.secret"))

type User struct {
	UserId   int    `json:"user_id"`
	UserName string `json:"user_name"`
	jwt.RegisteredClaims
}

// 生成token
func EncryptToken(data *User) string {
	claims := User{
		UserId:   data.UserId,
		UserName: data.UserName,
		RegisteredClaims: jwt.RegisteredClaims{
			ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour)),
			IssuedAt:  jwt.NewNumericDate(time.Now()),
			NotBefore: jwt.NewNumericDate(time.Now()),
			Issuer:    "Server",
		},
	}
	// 创建Token
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	signedString, _ := token.SignedString(secret)
	return signedString
}

// 解密token
func DecryptToken(str string, c *gin.Context) (error, gin.H) {
	tokenString := str

	// 传入token字符串和验证钩子函数，返回值就是一个Token结构体
	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
		// 验证签名算法是否匹配
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, fmt.Errorf("不匹配的签名算法: %s", token.Header["alg"])
		}
		// 返回验证密钥
		return secret, nil
	})
	if token.Valid {
		if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
			return nil, gin.H{"user": claims}
		}

	} else if errors.Is(err, jwt.ErrTokenMalformed) {
		return errors.New("传入的字符串甚至连一个token都不是..."), gin.H{}
	} else if errors.Is(err, jwt.ErrTokenExpired) || errors.Is(err, jwt.ErrTokenNotValidYet) {
		return errors.New("token合token已经过期或者还没有生效法"), gin.H{}
	} else {
		return errors.New("token处理异常..."), gin.H{}
	}
	return nil, gin.H{}

}
